﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
using MediaPortal.Util;
using MPMovieCatalog.Configuration;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Util;

namespace MPMovieCatalog.Forms
{
    public partial class SearchMovieForm : Form
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(SearchMovieForm));

        private LinkLabel m_detailLinkLabel;

        private WebBrowser m_webBrowser;

        private ListBox m_pictureListBox;

        private SplitContainer m_movieDetailsSplitContainer;

        public SearchMovieForm()
        {
            InitializeComponent();
            UpdateUI();

            ListViewAppender listBoxAppender = new ListViewAppender(logListView);
            listBoxAppender.Layout = new PatternLayout("%date - %message");
            listBoxAppender.Threshold = Level.Info;
            BasicConfigurator.Configure(listBoxAppender);
        }

        public string SearchString
        {
            get
            {
                return searchStringTextBox.Text;
            }

            set
            {
                searchStringTextBox.Text = value;
            }
        }

        public MovieInfo MovieInfo
        {
            get
            {
                if (searchResultTreeView.SelectedNode is MovieTreeNode)
                {
                    MovieTreeNode movieTreeNode = searchResultTreeView.SelectedNode as MovieTreeNode;
                    return movieTreeNode.FetchedMovie.MovieInfo;
                }
                return null;
            }
        }

        private void searchButton_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            searchResultSplitContainer.Panel2.Controls.Clear();
            searchResultTreeView.Nodes.Clear();
            searchResultTreeView.BeginUpdate();

            foreach (KeyValuePair<string, List<FetchedMovie>> pair in FetcherUtils.FindMovie(searchStringTextBox.Text))
            {
                TreeNode rootNode = new TreeNode(pair.Key);
                searchResultTreeView.Nodes.Add(rootNode);

                foreach (FetchedMovie fetchedMovie in pair.Value)
                {
                    rootNode.Nodes.Add(new MovieTreeNode(fetchedMovie));
                }
            }

            searchResultTreeView.EndUpdate();
            searchResultTreeView.ExpandAll();
            Cursor = Cursors.Arrow;
        }

        private void detailLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ShowMovieDetails(true);
        }

        private void searchResultTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            okButton.Enabled = searchResultTreeView.SelectedNode is MovieTreeNode;
            searchResultSplitContainer.Panel2.Controls.Clear();
            ShowMovieDetails(false);
        }

        private void ShowMovieDetails(bool forceDownloadDetails)
        {
            if (searchResultTreeView.SelectedNode is MovieTreeNode)
            {
                if (m_detailLinkLabel == null)
                {
                    m_detailLinkLabel = new LinkLabel();
                    m_detailLinkLabel.Dock = System.Windows.Forms.DockStyle.Fill;
                    m_detailLinkLabel.Text = ResourceUtils.GetString("search", 0);
                    m_detailLinkLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
                    m_detailLinkLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(this.detailLinkLabel_LinkClicked);
                }
                searchResultSplitContainer.Panel2.Controls.Add(m_detailLinkLabel);

                MovieInfo movieInfo = null;
                MovieTreeNode movieTreeNode = (MovieTreeNode)searchResultTreeView.SelectedNode;
                if (forceDownloadDetails)
                {
                    Cursor = Cursors.WaitCursor;
                    movieInfo = movieTreeNode.FetchedMovie.MovieInfo;
                    if (movieInfo != null)
                    {
                        DisplayMovieDetails(movieTreeNode.FetchedMovie);
                    }
                    Cursor = Cursors.Arrow;
                }
            }
        }

        private void DisplayMovieDetails(FetchedMovie fetchedMovie)
        {
            if (m_movieDetailsSplitContainer == null)
            {
                m_movieDetailsSplitContainer = new SplitContainer();
                m_movieDetailsSplitContainer.Dock = DockStyle.Fill;

                m_pictureListBox = new ListBox();
                m_pictureListBox.Dock = DockStyle.Fill;
                m_pictureListBox.SelectedIndexChanged += new EventHandler(m_pictureListBox_SelectedIndexChanged);

                m_webBrowser = new WebBrowser();
                m_webBrowser.Dock = DockStyle.Fill;
                m_webBrowser.IsWebBrowserContextMenuEnabled = false;

                m_movieDetailsSplitContainer.Panel1.Controls.Add(m_pictureListBox);
                m_movieDetailsSplitContainer.Panel2.Controls.Add(m_webBrowser);
            }
            searchResultSplitContainer.Panel2.Controls.Clear();
            searchResultSplitContainer.Panel2.Controls.Add(m_movieDetailsSplitContainer);

            m_pictureListBox.Items.Clear();
            foreach (MoviePicture picture in fetchedMovie.CoverArts)
            {
                m_pictureListBox.Items.Add(picture);
            }

            m_webBrowser.DocumentText = MPMovieCatalog.Util.TemplateUtils.TransformMovie(fetchedMovie.MovieInfo, null);
        }

        private void scriptsButton_Click(object sender, EventArgs e)
        {
            ConfigurationFormProperties properties = new ConfigurationFormProperties(false);
            properties.ShowScriptSection = true;

            using (ConfigurationForm settingForm = new ConfigurationForm(properties))
            {
                if (settingForm.ShowDialog() == DialogResult.OK)
                {
                    settingForm.SaveSettings();
                }
            }
        }

        private void m_pictureListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            MoviePicture picture = m_pictureListBox.SelectedItem as MoviePicture;
            if (string.IsNullOrEmpty(picture.FileName))
            {
                picture.FileName = MPMovieCatalog.Util.Utils.DownloadImage(picture.URL);
            }

            MovieTreeNode node = searchResultTreeView.SelectedNode as MovieTreeNode;
            node.FetchedMovie.MovieInfo.PictureFileName = picture.FileName;

            m_webBrowser.DocumentText = MPMovieCatalog.Util.TemplateUtils.TransformMovie(node.FetchedMovie.MovieInfo, null);
            Cursor = Cursors.Arrow;
        }


        internal class MovieTreeNode : TreeNode
        {
            public MovieTreeNode(FetchedMovie fetchedMovie)
                : base(fetchedMovie.Title)
            {
                this.FetchedMovie = fetchedMovie;
            }

            public FetchedMovie FetchedMovie { get; set; }
        }

        internal class ListViewAppender : AppenderSkeleton
        {
            private ListView m_listView = null;

            public ListViewAppender(ListView listView)
            {
                m_listView = listView;
            }

            protected override void Append(log4net.Core.LoggingEvent loggingEvent)
            {
                if (m_listView != null)
                {
                    StringWriter sw = new StringWriter();
                    Layout.Format(sw, loggingEvent);

                    ListViewItem item = new ListViewItem(sw.ToString());
                    if (loggingEvent.Level == Level.Error)
                    {
                        item.ToolTipText = loggingEvent.ExceptionObject.ToString();
                        item.ForeColor = System.Drawing.Color.Red;
                    }
                    m_listView.Items.Add(item);
                    item.Selected = true;
                    m_listView.EnsureVisible(item.Index);
                    m_listView.Update();
                }
            }
        }

        private void buttonPanel_Paint(object sender, PaintEventArgs e)
        {
            ControlPaint.DrawBorder3D(e.Graphics, this.buttonPanel.ClientRectangle, Border3DStyle.Etched, Border3DSide.Left);
        }

        private void buttonPanel_Resize(object sender, EventArgs e)
        {
            Invalidate();
        }

        private void UpdateUI()
        {
            this.Text = ResourceUtils.GetString("search", 1);
            searchGroupBox.Text = ResourceUtils.GetString("search", 2);
            searchStringLabel.Text = ResourceUtils.GetString("search", 3);
            searchButton.Text = ResourceUtils.GetString("search", 4);
            scriptsButton.Text = ResourceUtils.GetString("search", 5);
            searchResultGroupBox.Text = ResourceUtils.GetString("search", 6);
            columnHeader.Text = ResourceUtils.GetString("search", 7);
            okButton.Text = ResourceUtils.GetString("search", 8);
            cancelButton.Text = ResourceUtils.GetString("search", 9);
        }
    }
}